﻿using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.IService;
using Pay.TO;
using Pay.Service.Cache;
using System;
using System.Collections.Generic;
using System.Data.Entity.SqlServer;
using System.Linq;
using NPOI.SS.Formula.Functions;
using Pay.DTO.tenPay;

namespace Pay.Service
{
    public class PayHtmlService : ServiceBase, IPayHtmlService, IDisposable
    {
        private IUnitOfWork _iUnitOfWork;

        public PayHtmlService(IUnitOfWork iUnitOfWork) : base(iUnitOfWork)
        {
            _iUnitOfWork = iUnitOfWork;
        }

        public pay_html_dto Get(string id)
        {
            var query = context.PayHtmls.Where(c => c.Id == id);
            return query.FirstOrDefault().ToDtoObject<pay_html_dto>();
        }
        public pay_html_dto GetPayHtmlById(string id)
        {
            var result = context.PayHtmls.FirstOrDefault(c => c.Id == id);
            return result.ToDtoObject<pay_html_dto>();
        }
        public pay_html_dto GetPayByMerchantNo(string merchant_no)
        {
            return context.PayHtmls.FirstOrDefault(s => s.MerchantNo == merchant_no).ToDtoObject<pay_html_dto>();
        }
        public pay_html_dto Get(string merchant_no, string order_no)
        {
            var query = context.PayHtmls.Where(c => c.MerchantNo == merchant_no && c.OrderNo == order_no);
            return query.FirstOrDefault().ToDtoObject<pay_html_dto>();
        }

        public PagedResult<payment_data> Get(PayHtmlQuery payHtmlQuery)
        {
            var filter = PredicateBuilder.True<PayHtml>();
            filter = filter.And(c => c.PayType == "30");
            if (!string.IsNullOrEmpty(payHtmlQuery.order_no))
                filter = filter.And(c => c.OrderNo == payHtmlQuery.order_no || c.Id == payHtmlQuery.order_no);
            if (!string.IsNullOrEmpty(payHtmlQuery.q))
                filter = filter.And(c => c.Charge.Contains(payHtmlQuery.q));
            if (payHtmlQuery.pay_channel > 0)
            {
                filter = filter.And(c => c.PayType == payHtmlQuery.pay_channel.ToString());
            }
            if (payHtmlQuery.is_finish >= 0)
            {
                filter = filter.And(c => c.IsFinish == payHtmlQuery.is_finish);
            }
            var start_time = payHtmlQuery.start_time.ToUnix();
            if (payHtmlQuery.start_time.HasValue && payHtmlQuery.end_time.HasValue)
            {
                var end_time = payHtmlQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime >= start_time && c.CreateTime <= end_time);
            }
            else if (payHtmlQuery.start_time.HasValue && !payHtmlQuery.end_time.HasValue)
                filter = filter.And(c => c.CreateTime >= start_time);
            else if (!payHtmlQuery.start_time.HasValue && payHtmlQuery.end_time.HasValue)
            {
                var end_time = payHtmlQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime <= end_time);
            }
            var result = context.PayHtmls.FromCachePaged<PayHtml, pay_html_dto>(payHtmlQuery.page, payHtmlQuery.size, filter, orderBy => orderBy.OrderByDescending(c => c.CreateTime));
            return result.ToDtoPaged<pay_html_dto, payment_data>();
        }

        public bool Save(pay_html_dto dto, string tag = "")
        {
            dto.create_time = DateTime.Now;
            var model = new PayHtml();
            dto.ToDtoObject(model);
            context.PayHtmls.Add(model);
            int result = _iUnitOfWork.Commit(tag);
            return result > 0;
        }

        public bool Save(List<pay_html_dto> htmls)
        {
            foreach (var html in htmls)
            {
                var model = new PayHtml();
                html.ToDtoObject(model);
                context.PayHtmls.Add(model);
            }
            int result = _iUnitOfWork.Commit();
            return result > 0;
        }

        public ApiResultMessage Save(pay_html_model dto)
        {
            var model = new PayHtml();
            dto.ToDtoObject(model);
            model.Html = "";
            model.Id = Guid.NewGuid().ToString("N");
            model.CreateTime = DateTime.Now.ToUnix();
            context.PayHtmls.Add(model);
            int result = _iUnitOfWork.Commit();
            if (result > 0)
                return new ApiResultMessage("保存成功");
            else
                return new ApiResultMessage(0, "保存失败");
        }

        public int Update(pay_html_dto dto)
        {
            var model = context.PayHtmls.FindById(dto.id);
            dto.ToDtoObject<PayHtml>(model);
            int result = _iUnitOfWork.Commit();
            return result;
        }

        public int Update(string id, string pay_type)
        {
            int result = 0;
            var model = context.PayHtmls.Where(r => r.Id == id).FirstOrDefault();
            if (model != null)
            {
                model.PayType = pay_type;
                result = context.SaveChanges();
            }
            return result;
        }

        public int Remove(string id)
        {
            return Delete(new string[] { id });
        }

        public int Remove(string id, List<string> tags)
        {
            return Delete(new string[] { id }, tags);
        }
        public int Delete(string[] ids, List<string> tags = null)
        {
            if (tags == null)
                tags = new List<string>();
            if (ids.Length > 0)
            {
                var list = context.PayHtmls.Where(c => ids.Contains(c.Id)).ToList();
                list.DataForEach(model =>
                {
                    tags.Add(model.Id);
                    context.PayHtmls.Remove(model);
                });
                int result = _iUnitOfWork.Commit(tags.ToArray());
                return result;
            }
            return 0;
        }

        public int Delete(PayHtmlQuery payHtmlQuery)
        {
            var filter = PredicateBuilder.True<PayHtml>();
            if (!string.IsNullOrEmpty(payHtmlQuery.order_no))
                filter = filter.And(c => c.OrderNo == payHtmlQuery.order_no);
            if (!string.IsNullOrEmpty(payHtmlQuery.q))
                filter = filter.And(c => c.Charge.Contains(payHtmlQuery.q));
            if (payHtmlQuery.pay_channel > 0)
            {
                string likeStr = "%\"pay_channel\":" + payHtmlQuery.pay_channel + "%";
                filter = filter.And(c => SqlFunctions.PatIndex(likeStr, c.Charge) > 0);
            }
            var start_time = payHtmlQuery.start_time.ToUnix();
            if (payHtmlQuery.start_time.HasValue && payHtmlQuery.end_time.HasValue)
            {
                var end_time = payHtmlQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime >= start_time && c.CreateTime <= end_time);
            }
            else if (payHtmlQuery.start_time.HasValue && !payHtmlQuery.end_time.HasValue)
                filter = filter.And(c => c.CreateTime >= start_time);
            else if (!payHtmlQuery.start_time.HasValue && payHtmlQuery.end_time.HasValue)
            {
                var end_time = payHtmlQuery.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime <= end_time);
            }
            var tags = new List<string>();
            var list = context.PayHtmls.Where(filter).ToList();
            list.DataForEach(model =>
            {
                tags.Add(model.Id);
                context.PayHtmls.Remove(model);
            });
            int result = _iUnitOfWork.Commit(tags.ToArray());
            return result;
        }

        public List<pay_html_dto> GetPayHtmls(string pay_type)
        {
            var payhtmls = context.PayHtmls.Where(c => c.IsFinish == 0 && c.PayType == pay_type).ToList();
            if (payhtmls == null || payhtmls.Count() == 0)
                return new List<pay_html_dto>();
            return payhtmls.ToDtoList<pay_html_dto>();
        }
    }
}